package com.xique.door.biz.service.impl;


import com.xique.common.core.utils.DateUtils;
import com.xique.common.core.utils.MathUtil;
import com.xique.common.core.utils.OrikaUtil;
import com.xique.common.core.utils.StringUtils;
import com.xique.common.core.web.domain.AjaxResult;
import com.xique.door.bean.domain.*;
import com.xique.door.bean.request.buildHouse.BuildHouseBandUserRequest;
import com.xique.door.bean.request.buildHouse.BuildHouseAddRequest;
import com.xique.door.bean.request.buildHouse.BuildHouseDeleteUserRequest;
import com.xique.door.bean.request.permissionGroup.PermissionGroupDeleteUserRequest;
import com.xique.door.bean.validation.HouseValidation;
import com.xique.door.biz.service.IBuildHouseUserBizService;
import com.xique.door.biz.service.IPermissionGroupUserBizService;
import com.xique.door.mapper.BuildHouseUserMapper;
import com.xique.door.mapper.UserMapper;
import com.xique.door.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: caogq
 * @Date: 2021/9/15 08:49
 * @Description:
 */
@Service
public class BuildHouseBizService {

    @Autowired
    private HouseValidation houseValidation;

    @Autowired
    private IBuildBuildingService buildBuildingService;

    @Autowired
    private IBuildHouseService buildHouseService;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private BuildHouseUserPermissonBizService buildHouseUserPermissonBizService;

    @Autowired
    private BuildHouseUserMapper buildHouseUserMapper;

    @Autowired
    private IPermissionGroupService permissionGroupService;

    @Autowired
    private IPermissionGroupUserBizService permissionGroupUserBizService;
    @Autowired
    private IBuildHouseUserBizService buildHouseUserBizService;

    @Autowired
    private IParkInfoService parkInfoService;


    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public AjaxResult addHouse(BuildHouseAddRequest request) {
        BuildHouse buildHouse = OrikaUtil.convert(request, BuildHouse.class);
        //校验
        AjaxResult result = houseValidation.addHouseValidation(buildHouse);
        BuildBuilding buildBuilding = buildBuildingService.selectBuildBuildingById(buildHouse.getBuildingId());
        buildHouse.setCode(buildBuilding.getCode() + buildHouse.getHouseCode());
        buildHouse.setBuildingName(buildBuilding.getBuildingName());

        if (AjaxResult.isError(result)) {
            return result;
        }
        int i = buildHouseService.insertBuildHouse(buildHouse);

        if (request.getUserId() == null) {
            return i > 0 ? AjaxResult.success() : AjaxResult.error();
        }

        //业主相关
        User user = userMapper.selectUserById(request.getUserId());
        user.setHouseId(buildHouse.getId());
        user.setBuildingId(String.valueOf(buildHouse.getBuildingId()));
        BuildHouseUser buildHouseUser = new BuildHouseUser();
        buildHouseUser.setUserId(user.getId());
        buildHouseUser.setHouseId(buildHouse.getId());
        buildHouseUser.setHouseName(buildHouse.getHouseName());
        buildHouseUser.setUserName(user.getUserName());
//        buildHouseUser.setRelation("18");
        buildHouseUser.setIdentityType("0");
        buildHouseUser.setBuildingId(buildBuilding.getId());
        buildHouseUser.setBuildingName(buildBuilding.getBuildingName());
        int houseUserResult = buildHouseUserMapper.insertBuildHouseUser(buildHouseUser);

        //TODO 绑定用户到所属楼栋对应的设备对应的设备用户表。
        return houseUserResult > 0 ? AjaxResult.success() : AjaxResult.error();
    }

    public List<User> selectAllocatedList(User user) {
        List<User> users = userMapper.selectAllocatedHouseUser(user);
        return users;
    }

    public List<User> selectUnAllocatedList(User user) {
        List<User> users = userMapper.selectUnAllocatedList(user);
        return users;
    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public AjaxResult houseAddAllUser(BuildHouseBandUserRequest request) {
//        List<String> ids = Arrays.asList(request.getUserIds().split(","));
//        for (String userId : ids) {
//            request.setUserId(Long.valueOf(userId));
//            AjaxResult result = buildHouseUserBizService.addHouseUser(request);
//            if (AjaxResult.isError(result)){
//                return AjaxResult.error();
//            }
//        }
        return buildHouseUserBizService.addHouseUser(request);
    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public AjaxResult houseRemoveUser(BuildHouseDeleteUserRequest request) {
//        //基础参数准备
//        Long houseId = Long.valueOf(user.getHouseId());
//        Long userId = user.getId();
//        BuildHouse buildHouse = buildHouseService.selectBuildHouseById(houseId);
//        Long buildingId = buildHouse.getBuildingId();

//        //2、删除用户和区域权限组关联（判断用户是否在该区域下拥有别的房屋）
//        BuildHouseUser buildingSearch = new BuildHouseUser();
//        buildingSearch.setUserId(userId);
//        buildingSearch.setBuildingId(buildingId);
//        List<BuildHouseUser> buildingHouses = buildHouseUserMapper.selectBuildHouseUserList(buildingSearch);
//        if (buildingHouses.size() ==1 && buildingHouses.get(0).getHouseId().equals(houseId)) {
//            BuildBuilding building = buildBuildingService.selectBuildBuildingById(buildingId);
//            deleteUserGroup(Collections.singletonList(building.getAreaId()), BuildConstant.BuildType.AREA, userId);
//        }
//
//        //3、删除用户和楼栋权限组关联（判断用户是否在该楼栋下拥有别的房屋）
//        buildingSearch.setBuildingId(buildingId);
//        List<BuildHouseUser> areaHouses = buildHouseUserMapper.selectBuildHouseUserList(buildingSearch);
//        if (buildingHouses.size() ==1 && areaHouses.get(0).getHouseId().equals(houseId)){
//            //当且仅当用户在该楼栋下只有一个房屋，才去解绑用户和楼栋权限组
//            deleteUserGroup(Collections.singletonList(buildingId), BuildConstant.BuildType.BUILDING, userId);
//
//        }

        return buildHouseUserBizService.deleteHouseUser(request);
    }

    public AjaxResult batchAdd(BuildHouseAddRequest request) {
        List<BuildHouse> buildHouses = new ArrayList<>();
        List<String> houseCodes = request.getHouses().stream().map(BuildHouseAddRequest::getHouseCode).collect(Collectors.toList());
        BuildHouse search = new BuildHouse();
        search.setBuildingId(request.getBuildingId());
        search.setHouseCodes(houseCodes);
        List<BuildHouse> result = buildHouseService.selectBuildHouseList(search);
        ParkInfo parkInfo = parkInfoService.selectParkInfoById(request.getParkId());
        if (!result.isEmpty()) {
            return AjaxResult.error("门牌号重复！");
        }
        for (BuildHouseAddRequest house : request.getHouses()) {
            BuildBuilding buildBuilding = buildBuildingService.selectBuildBuildingById(request.getBuildingId());
            BuildHouse buildHouse = new BuildHouse();
            buildHouse.setBuildingId(request.getBuildingId());
            buildHouse.setBuildingName(buildBuilding.getBuildingName());
            buildHouse.setEstate(request.getEstate());
            if (request.getMaxInNumber()!=null&&!"".equals(request.getMaxInNumber())) {
                buildHouse.setMaxInNumber(request.getMaxInNumber());
            } else if (parkInfo.getMaxInNumber() == null) {
                buildHouse.setMaxInNumber(10);
            } else {
                buildHouse.setMaxInNumber(parkInfo.getMaxInNumber());
            }
            buildHouse.setBuildArea(house.getBuildArea());
            buildHouse.setDecoration(house.getDecoration());
            buildHouse.setDirection(house.getDirection());
            buildHouse.setHouseCode(house.getHouseCode());
            buildHouse.setCode(buildBuilding.getCode() + house.getHouseCode());
            buildHouse.setHouseName(buildHouse.getHouseCode() + "室");
            buildHouse.setHouseCode(house.getHouseCode());
            buildHouse.setRoomNum(house.getRoomNum());
            buildHouse.setOfficeNum(house.getOfficeNum());
            buildHouse.setToiletNum(house.getToiletNum());
            buildHouse.setParkId(request.getParkId());

            buildHouse.setDelFlag("0");

            buildHouse.setStatus("normal");

            buildHouses.add(buildHouse);
        }
        int i = buildHouseService.insertBuildHouses(buildHouses);
        return i > 0 ? AjaxResult.success() : AjaxResult.error();
    }

    /**
     * 住户权限组解绑（区域、楼栋）
     *
     * @param foreignIds
     * @param foreignType
     * @param userId
     * @return
     */
    public AjaxResult deleteUserGroup(List<Long> foreignIds, String foreignType, Long userId) {
        List<PermissionGroup> permissionGroupList = permissionGroupService.selectPermissionGroupListByForeignIds(foreignIds, foreignType);

        PermissionGroupDeleteUserRequest userRequest = new PermissionGroupDeleteUserRequest();
        userRequest.setUserId(userId);
        userRequest.setGroupId(permissionGroupList.get(0).getId());
        return permissionGroupUserBizService.deleteUser(userRequest);
    }

    public AjaxResult houseAddUser(User user) {
        //判断业主是否已存在
        Boolean ownerExistFlag = this.judgeIsHouseOwnerExist(user.getHouseId());
        if (("0").equals(user.getIdentityType()) && ownerExistFlag == true) {
            return AjaxResult.error("业主已存在！");
        }
        List<User> users = userMapper.selectUserList(new User(user.getParkId(), user.getPhone()));
        if (!users.isEmpty()) {
            //用户已存在 更新用户信息
            User oldUser = users.get(0);
            BuildHouseUser buildHouseUser = new BuildHouseUser();
            buildHouseUser.setHouseId(Long.valueOf(user.getHouseId()));
            buildHouseUser.setUserId(oldUser.getId());
            List<BuildHouseUser> buildHouseUsers = buildHouseUserMapper.selectBuildHouseUserList(buildHouseUser);
            if (!buildHouseUsers.isEmpty()) {
                return AjaxResult.error("用户已绑定该房屋！");
            }
            oldUser.setFaceUrl(user.getFaceUrl());
            oldUser.setUserName(user.getUserName());
            oldUser.setHouseId(user.getHouseId());
            oldUser.setLiveWay(user.getLiveWay());
            oldUser.setRelation(user.getRelation());
            oldUser.setIdentityType(user.getIdentityType());
            oldUser.setDueDate(user.getDueDate());
            oldUser.setCheckInDate(user.getCheckInDate());
            userMapper.updateUser(oldUser);
            user = oldUser;
        } else {
            user.setCreateTime(DateUtils.getNowDate());
            //32位id生成逻辑 = 13位时间戳+19位随机数
            String customId = System.currentTimeMillis() + MathUtil.getRandom(19);
            user.setCustomId(customId);
            user.setVisitorType("0");
            userMapper.insertUser(user);
        }
        AjaxResult result = buildHouseUserPermissonBizService.addUserHousePermissGroup(user);

        return result;
    }

    /**
     * 判断房屋是否已存在业主
     *
     * @return
     */
    public Boolean judgeIsHouseOwnerExist(Long houseId) {
        BuildHouseUser buildHouseUser = new BuildHouseUser();
        buildHouseUser.setHouseId(houseId);
        List<BuildHouseUser> buildHouseUsers = buildHouseUserMapper.selectBuildHouseUserList(buildHouseUser);
        List<BuildHouseUser> ownerList = buildHouseUsers.stream().filter(e -> "0".equals(e.getIdentityType())).collect(Collectors.toList());
        return !ownerList.isEmpty() ? true : false;
    }

    /**
     * @description: 查询一个用户的房号，取房号的后四位，多房号用逗号分割
     * @author caogq
     * @date: 2021/11/10 11:55
     * @Param
     */

    public String selectCommandHouseNumberByUser(User user) {
        BuildHouseUser buildHouseUser = new BuildHouseUser();
        buildHouseUser.setUserId(user.getId());
        List<BuildHouseUser> buildHouseUsers = buildHouseUserMapper.selectBuildHouseUserList(buildHouseUser);
        if (buildHouseUsers.isEmpty()) {
            return null;
        }
        return "";
    }
}
